
using System.Collections.Generic;
#if (!WindowsCE)
using System;
using System.Linq.Expressions;
#endif
using NUnit.Framework;
using TypeMock;
using ValidationFramework.Tests.TestHelpers;

namespace ValidationFramework.Tests
{

	public class DataErrorInfoValidatableBaseTest
	{

		public class MockDataErrorInfoValidatable : DataErrorInfoValidatableBase
		{
			#region Fields

			public const string PropertyMember = "Property";

			#endregion

            #region Methods

            public new void ValidateProperty(string propertyName)
            {
				base.ValidateProperty(propertyName);
            }
#if (!WindowsCE)
            public new void ValidateProperty<TProperty>(Expression<Func<TProperty>> expression)
            {
                base.ValidateProperty(expression);
            }
#endif
            #endregion

            #region Properties

            private string property;

			[AlwaysFail(Id = "1")]
			[AlwaysPass(Id = "2")]
			public string Property
			{
				get
				{
					return property;
				}
				set
				{
					if (property != value)
					{
						property = value;
						ValidateProperty(PropertyMember);
					}
				}
			}

			#endregion
		}


		[TestFixture]
        public class Constructor : BaseTypeMock
		{
			[Test]
			public void Simple()
			{
				Validation.Initialize();
				var mock = new MockDataErrorInfoValidatable();
				Assert.AreEqual(null, mock.RuleSet);
			}
		}

		[TestFixture]
		public class RuleSet : BaseTypeMock
		{
			[Test]
			public void Simple()
			{
				Validation.Initialize();
				var mock = new MockDataErrorInfoValidatable
				{
					RuleSet = "ruleSet"
				};
				Assert.AreEqual("RULESET", mock.RuleSet);
			}
		}


        [TestFixture]
        public class Item : BaseTypeMock
        {

            [Test]
            public void NoErrors()
            {
				Validation.Initialize();
				var mock = new MockDataErrorInfoValidatable
				{
					RuleSet = "ruleSet"
				};

                IList<ValidationError> validationResults = new List<ValidationError>();
                using (var recorder = RecorderManager.StartRecording())
                {
                    recorder.ExpectAndReturn(mock.PropertyValidationManager.GetResultsInError("Property"), validationResults);
                }
                Assert.AreEqual(string.Empty, mock["Property"]);

            }

            [Test]
            public void Errors()
            {
				Validation.Initialize();
                const string expectedErrorMessage = "ErrorMessage";
				var fakeDescriptor = new FakeReflectionInfo();
				var validationResult = new ValidationError(null, expectedErrorMessage, null, fakeDescriptor);
                var mock = new MockDataErrorInfoValidatable
				{
								RuleSet = "ruleSet"
                           	};
                IList<ValidationError> validationResults = new List<ValidationError> { validationResult };

                using (var recorder = RecorderManager.StartRecording())
                {
                    recorder.ExpectAndReturn(mock.PropertyValidationManager.GetResultsInError("Property"), validationResults);
                }
                Assert.AreEqual(expectedErrorMessage, mock["Property"]);

            }
        }
        
#if (!WindowsCE)
		[TestFixture]
		public class GetErrors : BaseTypeMock
		{

			[Test]
			public void Simple()
			{
				Validation.Initialize();
				var mock = new MockDataErrorInfoValidatable
							{
								RuleSet = "ruleSet"
							};
				using (var recorder = RecorderManager.StartRecording())
				{
					recorder.ExpectAndReturn(mock["Property"], null);
				}
				mock.GetError(() => mock.Property);
			}
		}
#endif

        [TestFixture]
        public class ValidateProperty : BaseTypeMock
        {

            [Test]
            public void Simple()
            {
				Validation.Initialize();
				var mock = new MockDataErrorInfoValidatable
				{
					RuleSet = "ruleSet"
				};
                using (var recorder = RecorderManager.StartRecording())
                {
                    mock.PropertyValidationManager.Validate("Property");
                }
                mock.ValidateProperty("Property");
            }

            [Test]
            public void IgnoreNoErrors()
            {
				Validation.Initialize();
				var mock = new MockDataErrorInfoValidatable
				{
					RuleSet = "ruleSet"
				};
                using (RecorderManager.StartRecording())
                {
                    mock.PropertyValidationManager.Validate("Property");
                }
                mock.ValidateProperty("Property");
            }

#if (!WindowsCE)
            [Test]
            public void SimpleExpression()
            {
				Validation.Initialize();
				var mock = new MockDataErrorInfoValidatable
				{
					RuleSet = "ruleSet"
				};
                using (var recorder = RecorderManager.StartRecording())
                {
                    mock.PropertyValidationManager.Validate("Property");
                }
                mock.ValidateProperty(() => mock.Property);
            }
            [Test]
            public void IgnoreNoErrorsExpression()
            {
				Validation.Initialize();
				var mock = new MockDataErrorInfoValidatable()
				{
					RuleSet = "ruleSet"
				};
                using (RecorderManager.StartRecording())
                {
                    mock.PropertyValidationManager.Validate("Property");
                }
                mock.ValidateProperty(() => mock.Property);
            }
#endif
        }
	}
}